<?php

require_once( 'flexical/model/feed.php' );
require_once( 'flexical/model/query.php' );
require_once( 'flexical/model/event.php' );

require_once( 'flexical/service/cao.php' );
require_once( 'flexical/service/cao-exception.php' );

require_once( 'Zend/Loader.php' );

Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
Zend_Loader::loadClass('Zend_Gdata_Calendar_EventQuery');

class Flexical_Service_CAO_Zend extends Flexical_Service_CAO
{
	public function __construct()
	{
		;
	}

	private function load_zend_framework()
	{
		if ( ! class_exists( 'Zend_Loader' ) )
		{
			require_once( 'Zend/Loader.php' );
			Zend_Loader::loadClass('Zend_Gdata');
			Zend_Loader::loadClass('Zend_Gdata_AuthSub');
			Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
			Zend_Loader::loadClass('Zend_Gdata_Calendar');
			Zend_Loader::loadClass('Zend_Gdata_Calendar_EventQuery');
		}
	}

	public function get_connection( $username, $password )
	{
		$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;

		try
		{
			$client = Zend_Gdata_ClientLogin::getHttpClient( $username, $password, $service );
		}

		catch ( Exception $e )
		{
			throw new Flexical_Service_CAO_Exception( 'Error logging into Google Calendar', 0, $e );
		}

		return new Zend_Gdata_Calendar( $client );
	}

	public function read_feeds( $username, $password )
	{
		$connection = $this->get_connection( $username, $password );

		try
		{
			$calendar_list_feed = $connection->getCalendarListFeed();
		}

		catch ( Exception $e )
		{
			throw new Flexical_Service_CAO_Exception( 'Error reading list of calendars', 0, $e );
		}

		$feeds = array();

		foreach ( $calendar_list_feed as $cal )
		{
			if ( $cal->title->text == null || $cal->title->text == '' )
			{
				continue;
			}

			$feed = $this->build_feed( $cal );
			$feeds[ $feed->url ] = $feed;
		}

		return $feeds;
	}

	public function build_feed( $cal )
	{
		$feed = new Flexical_Model_Feed();

		$feed->title    = $cal->title->text;
		$feed->color    = $cal->color->value;
		$feed->url      = $this->fix_url( $cal->id->text );
		$feed->timezone = $cal->timezone->value;

		return $feed;
	}

	public function fix_url( $url )
	{
		$pattern = '/\/default\//';
		$replacement = '/';
		return preg_replace( $pattern, $replacement, $url ) . '/public/full';
	}

	public function read_events( $feed, $query )
	{
		if ( $query == null )
		{
			$query = new Flexical_Model_Query();
		}

		$calendar = new Zend_Gdata_Calendar();
		$event_query = $calendar->newEventQuery( $feed->url );
		$this->build_event_query( $event_query, $feed, $query );

		try
		{
			$event_feed = $calendar->getCalendarEventFeed( $event_query );
			return $this->build_events( $event_feed, $feed->timezone );
		}

		catch ( Exception $e )
		{
			echo( '<!-- DEBUG ' . $e . ' -->' );
			throw new Flexical_Service_CAO_Exception( 'Error reading Google Calendar feed ' . $feed->title . ' (' . $feed->url . ')', 0, $e );
		}
	}

	private function build_event_query( $event_query, $feed, $query )
	{
		$event_query->setUser( null );
		$event_query->setVisibility( null );
		$event_query->setProjection( null );

		$event_query->setFutureEvents( $query->futureevents ? 'true' : 'false' );
		$event_query->setSingleEvents( true );
		$event_query->setOrderBy( $query->orderby );
		$event_query->setSortOrder( $query->sortorder );
	}

	public function flush_event_cache()
	{
		;
	}

	public function build_events( $event_feed, $timezone )
	{
		$events = array();

		foreach ( $event_feed as $event )
		{
			$model_event = new Flexical_Model_Event();

			$model_event->title = $event->title->text;
			$model_event->id = $event->id;
			$model_event->description = $event->content;

			foreach ( $event->where as $where )
			{
				$model_event->location = $where->valueString;
				break;
			}

			foreach ( $event->when as $when )
			{
				$model_event->all_day_event = $this->is_all_day_event( $when->startTime );
				$model_event->start_date = $this->get_timestamp( $when->startTime, $event_feed->timezone );
				$model_event->end_date = $this->get_timestamp( $when->endTime, $event_feed->timezone );
				$model_event->timezone = $timezone;

				break;
			}

			$events[] = $model_event;
		}

		return $events;
	}

	public function test_feed( $feed )
	{
		$this->load_zend_framework();

		$calendar = new Zend_Gdata_Calendar();

		$event_query = $calendar->newEventQuery( $feed->url );
		$event_query->setUser( null );
		$event_query->setVisibility( null );
		$event_query->setProjection( null );

		try
		{
			$event_feed = $calendar->getCalendarEventFeed( $event_query );
		}

		catch ( Exception $e )
		{
			return false;
		}

		return true;		
	}

	private function is_all_day_event( $string )
	{
		return preg_match( '/^\d\d\d\d-\d\d-\d\d$/', $string );
	}
	
	private function get_timestamp( $string, $timezone )
	{
		return intval( date_create( $string, new DateTimeZone( $timezone ) )->format( 'U' ) );
	}
}

?>
